<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="WTtON" id="WTtON"><span data-lake-id="u26b2e321" id="u26b2e321">典型回答</span></h1>
  <p data-lake-id="u9bf7240e" id="u9bf7240e"><br></p>
  <p data-lake-id="u4cdc5b4c" id="u4cdc5b4c"><span data-lake-id="u70c19235" id="u70c19235">线程同步指的就是让多个线程之间按照顺序访问同一个共享资源，避免因为并发冲突导致的问题，主要有以下几种方式：</span></p>
  <p data-lake-id="u7169c497" id="u7169c497"><span data-lake-id="ub0c0dabf" id="ub0c0dabf">​</span><br></p>
  <p data-lake-id="u31b30263" id="u31b30263"><strong><span data-lake-id="ub13d6d1a" id="ub13d6d1a">synchronized</span></strong><span data-lake-id="u214a0bb9" id="u214a0bb9">：Java中最基本的线程同步机制，可以修饰代码块或方法，保证同一时间只有一个线程访问该代码块或方法，其他线程需要等待锁的释放。</span></p>
  <p data-lake-id="u56ec3f03" id="u56ec3f03"><span data-lake-id="ua9a70ccb" id="ua9a70ccb">​</span><br></p>
  <pre lang="java"><code>
public synchronized void synchronizedMethod() {
    // 同步的代码块
}

</code></pre>
  <p data-lake-id="uc208f004" id="uc208f004"><span data-lake-id="ubfdea641" id="ubfdea641">​</span><br></p>
  <p data-lake-id="u46c0bc91" id="u46c0bc91"><strong><span data-lake-id="u1d44701a" id="u1d44701a">ReentrantLock</span></strong><span data-lake-id="ud40440e5" id="ud40440e5">：与synchronized关键字类似，也可以保证同一时间只有一个线程访问共享资源，但是更灵活，支持公平锁、可中断锁、多个条件变量等功能。</span></p>
  <p data-lake-id="u2d4e6e70" id="u2d4e6e70"><span data-lake-id="ua3e82802" id="ua3e82802">​</span><br></p>
  <pre lang="java"><code>
import java.util.concurrent.locks.ReentrantLock;

private final ReentrantLock lock = new ReentrantLock();

public void someMethod() {
    lock.lock();
    try {
        // 同步的代码块
    } finally {
        lock.unlock();
    }
}

</code></pre>
  <p data-lake-id="u60edb09b" id="u60edb09b"><span data-lake-id="ue509b244" id="ue509b244">​</span><br></p>
  <p data-lake-id="ua2729d0c" id="ua2729d0c"><strong><span data-lake-id="u72111d0d" id="u72111d0d">Semaphore</span></strong><span data-lake-id="u6a127bbe" id="u6a127bbe">：允许多个线程同时访问共享资源，但是限制访问的线程数量。可以用于控制并发访问的线程数量，避免系统资源被过度占用。</span></p>
  <p data-lake-id="u658b166b" id="u658b166b"><span data-lake-id="uaa6fee72" id="uaa6fee72">​</span><br></p>
  <pre lang="java"><code>
import java.util.concurrent.Semaphore;

private final Semaphore semaphore = new Semaphore(2);

public void accessResource() throws InterruptedException {
    semaphore.acquire(); // 获取许可
    try {
        // 访问共享资源
    } finally {
        semaphore.release(); // 释放许可
    }
}

</code></pre>
  <p data-lake-id="ub162973d" id="ub162973d"><br></p>
  <p data-lake-id="u1776ef1a" id="u1776ef1a"><strong><span data-lake-id="u6636a116" id="u6636a116">CountDownLatch</span></strong><span data-lake-id="ue2fab022" id="ue2fab022">：允许一个或多个线程等待其他线程执行完毕之后再执行，可以用于线程之间的协调和通信。</span></p>
  <p data-lake-id="ub7c1f8da" id="ub7c1f8da"><span data-lake-id="u6c1b2c99" id="u6c1b2c99">​</span><br></p>
  <pre lang="java"><code>
import java.util.concurrent.CountDownLatch;

private final CountDownLatch latch = new CountDownLatch(3);

public void doWork() throws InterruptedException {
    // 每个线程完成工作后调用 latch.countDown()
    latch.countDown();
    // 主线程等待所有工作线程完成
    latch.await();
}

</code></pre>
  <p data-lake-id="u77bacf8a" id="u77bacf8a"><br></p>
  <p data-lake-id="ucd08efc5" id="ucd08efc5"><strong><span data-lake-id="ub7e62f5e" id="ub7e62f5e">CyclicBarrier</span></strong><span data-lake-id="ue96f25a6" id="ue96f25a6">类：允许多个线程在一个栅栏处等待，直到所有线程都到达栅栏位置之后，才会继续执行。</span></p>
  <p data-lake-id="u3c85b94a" id="u3c85b94a"><span data-lake-id="u68f10166" id="u68f10166">​</span><br></p>
  <pre lang="java"><code>
import java.util.concurrent.CyclicBarrier;

private final CyclicBarrier barrier = new CyclicBarrier(3);

public void doWork() throws InterruptedException, BrokenBarrierException {
    // 每个线程执行到 barrier.await() 处等待
    barrier.await();
    // 所有线程到达屏障点后同时继续执行
}

</code></pre>
  <p data-lake-id="uc9ebf8b9" id="uc9ebf8b9"><span data-lake-id="ufb0cae73" id="ufb0cae73">​</span><br></p>
  <p data-lake-id="ufb46bb81" id="ufb46bb81"><br></p>
  <p data-lake-id="u5d9af082" id="u5d9af082"><strong><span data-lake-id="u0c156417" id="u0c156417">Phaser</span></strong><span data-lake-id="uc3aa46b2" id="uc3aa46b2">：与CyclicBarrier类似，也是一种多线程同步工具，但是支持更灵活的栅栏操作，可以动态地注册和注销参与者，并可以控制各个参与者的到达和离开。</span></p>
  <p data-lake-id="u289cdbd0" id="u289cdbd0"><span data-lake-id="u5c6ef928" id="u5c6ef928">​</span><br></p>
  <pre lang="java"><code>
import java.util.concurrent.Phaser;

private final Phaser phaser = new Phaser(3);

public void doWork() {
    // 线程执行到某个阶段，调用 phaser.arriveAndAwaitAdvance()
    phaser.arriveAndAwaitAdvance();
    // 所有线程到达阶段后同时继续执行下一阶段
}

</code></pre>
  <p data-lake-id="ucfe52e8d" id="ucfe52e8d"><span data-lake-id="u3d1d5361" id="u3d1d5361">​</span><br></p>
 </body>
</html>